package com.member.api.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.member.model.DES3Utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 2.7.4 免密支付-（二要素或四要素）消费
 */
public class TestYFHInterfaceByPayElesSecretFree {
	
	//接入方
	public static final String UNIONPAY_KEY_ACCESSID = "xxxxxxxxx"; // 接入方 银联平台分配的用户信息加密 key
	public static final String UNIONPAY_ORGCODE_ACCESSID = "xxxxxxxxx"; // 接入方 银联平台分配的OrgCode

	public static void main(String[] args) throws Exception {
		// 免密支付
		payElesSecretFree();
	}

	//免密支付 
	public static void payElesSecretFree() throws Exception {
		String userName = "xxxxxxxxx";
		String cardID = "xxxxxxxxx";
		String bankCardNo ="xxxxxxxxx";
		String mobile ="xxxxxxxxx";
		try {
			userName = DES3Utils.encryptDESCBC(userName, UNIONPAY_KEY_ACCESSID);// 姓名
			cardID = DES3Utils.encryptDESCBC(cardID, UNIONPAY_KEY_ACCESSID);
			bankCardNo = DES3Utils.encryptDESCBC(bankCardNo, UNIONPAY_KEY_ACCESSID);
			mobile = DES3Utils.encryptDESCBC(mobile, UNIONPAY_KEY_ACCESSID);
		} catch (Exception e) {
			e.printStackTrace();
		}
		Map<String, String> json = new HashMap<>();
		json.put("channelId", "xxxxxxxxx");// 接入方id，银联提供
		json.put("hospitalId", "xxxxxxxxx");//银联提供
		json.put("timeStamp", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
		json.put("notifyUrl", "xxxxxxxxx");
		json.put("orderId", "YHF00210003003329201100005"); // 修改
		json.put("txnAmt", "1200");
		json.put("reqReserved", "");
		json.put("bizType", "1");
		json.put("payType", "02");// 01：二要素扣款模式 02：四要素扣款模式
		json.put("termId", "");

		json.put("orderDesc", "医疗费用"); // 华夏银行支付必填
		json.put("bizItemDesc", "医保支付方式");// 华夏银行支付必填

		json.put("userName", userName);
		json.put("cardID", cardID);
		json.put("bankCardNo", bankCardNo);
		json.put("mobile", mobile);

		String riskInfo = "{" +
				"deviceID=178fc01efdc9b425&" +
				"deviceType=1&" +
				"accountIdHash=5692279&" +
				"usrRgstrDt=20230116&" +
				"sourceIP=219.232.97.208&" +
				"deviceLocation=+31.32/-112.97" + // deviceLocation 必填 可上送机构或医疗经纬度
				"&deviceName=iPhone" +
				"}";
		json.put("riskRateInfo", base64(riskInfo, "UTF-8"));


		System.out.println("接口入参：" + JSON.toJSONString(json));
		String url = "http://58.33.119.64/services/rest/v1/trade/payElesSecretFree";
		String res = sendPostToCloudPlatform(url,
				JSON.toJSONString(json), UNIONPAY_KEY_ACCESSID, UNIONPAY_ORGCODE_ACCESSID);
		System.out.println("接口出參：{}" + JSON.toJSONString(res));
	}

	private static String sendPostToCloudPlatformChannel(String urlTail, String json, String unionPayKey,
			String unionPayOrgCode) {
		String content = "";
		CloseableHttpClient httpClient = HttpClients.createDefault();
		String authorization = generateSignature(json, unionPayKey);// unionPayKey 银联提供 key 用于用户信息加密

		HttpPost httpPost = new HttpPost(urlTail);
		// 请求头的设置
		httpPost.setHeader("OrgCode", unionPayOrgCode);// OrgCode
		httpPost.setHeader("Authorization", authorization);
		httpPost.setHeader("Accept", "application/json, text/plain, */*");
		httpPost.setHeader("Content-type", "application/json;charset=utf-8");
		// 参数配置 编码格式配置
		StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
		httpPost.setEntity(stringEntity);
		// 执行请求操作，并拿到结果（同步阻塞）
		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(httpPost);
			content = EntityUtils.toString(response.getEntity());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return content;
	}

	private static String sendPostToCloudPlatform(String urlTail, String json, String uninopayKey,
			String unionpayOrgCode) {
		String content = "";
		CloseableHttpClient httpClient = HttpClients.createDefault();
		String authorization = generateSignature(json, uninopayKey);// privateKey 银联提供 key 用于用户信息加密
		HttpPost httpPost = new HttpPost(urlTail);
		// 请求头的设置
		httpPost.setHeader("OrgCode", unionpayOrgCode);// OrgCode
		httpPost.setHeader("Authorization", authorization);
		httpPost.setHeader("Accept", "application/json, text/plain, */*");
		httpPost.setHeader("Content-type", "application/json;charset=utf-8");
		// 参数配置 编码格式配置
		StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
		httpPost.setEntity(stringEntity);
		// 执行请求操作，并拿到结果（同步阻塞）
		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(httpPost);
			content = EntityUtils.toString(response.getEntity());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return content;
	}

	/**
	 * 生成验签内容
	 * 
	 * @return
	 */
	public static String generateSignature(String json, String authorizationKey) {
		String sign = null;
		try {
			sign = encode(JSONObject.parseObject(json), authorizationKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sign;
	}

	private static String PARAM_AND_CHAR = "&";
	private static String PARAM_ASSIGN_CHAR = "=";
	private static String base64(String input,String encoding) {
		try {
			return new String(Base64.encodeBase64(input.getBytes(encoding)));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * @param requestData
	 *            参数
	 * @param authorizationKey
	 *         
	 * @return
	 * @throws NoSuchAlgorithmException
	 */
	public static String encode(Map<String, Object> requestData, String authorizationKey)
			throws NoSuchAlgorithmException {
		String sortRespJson = buildSortJson(requestData) + authorizationKey;
		return md5(sortRespJson);
	}

	private static String buildSortJson(Map<String, Object> requestData) {
		StringBuffer sortSb = new StringBuffer();
		List<String> jsonKeys = new ArrayList<>();
		for (String key : requestData.keySet()) {
			jsonKeys.add(key);
		}
		Collections.sort(jsonKeys);
		for (String jsonKey : jsonKeys) {
			if (requestData.get(jsonKey) != null) {
				if (sortSb.length() > 0) {
					sortSb.append(PARAM_AND_CHAR);
				}
				sortSb.append(jsonKey).append(PARAM_ASSIGN_CHAR).append(requestData.get(jsonKey));
			}
		}
		return sortSb.toString();
	}

	/** 获得MD5加密算法 **/
	private static String md5(String inStr) {
		String result = "";
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
			// 这句是关键
			md5.update(inStr.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		byte b[] = md5.digest();
		int i;
		StringBuffer buf = new StringBuffer("");
		for (int offset = 0; offset < b.length; offset++) {
			i = b[offset];
			if (i < 0) {
				i += 256;
			}
			if (i < 16) {
				buf.append("0");
			}
			buf.append(Integer.toHexString(i));
		}
		result = buf.toString();

		return result;
	}

	private static String sendPostToCloudPlatform(String urlTail, String json) {
		String content = "";
		CloseableHttpClient httpClient = HttpClients.createDefault();

		HttpPost httpPost = new HttpPost(urlTail);
		// 请求头的设置
		httpPost.setHeader("Accept", "application/json, text/plain, */*");
		httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
		// 参数配置 编码格式配置
		StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
		httpPost.setEntity(stringEntity);
		// 执行请求操作，并拿到结果（同步阻塞）
		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(httpPost);
			content = EntityUtils.toString(response.getEntity());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return content;
	}
}
